package com.itita.ww2.model.item.prop;

import java.util.Map.Entry;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.util.concurrent.AtomicLongMap;
import com.itita.ww2.core.WW2Exception;
import com.itita.ww2.data.ChestRuleConfig;
import com.itita.ww2.data.ChestRuleConfig.ContentType;
import com.itita.ww2.data.ChestRuleConfig.RandomType;
import com.itita.ww2.data.ChestRuleConfig.RuleType;
import com.itita.ww2.game.user.UserArmyManager;
import com.itita.ww2.game.user.UserInventoryManager;
import com.itita.ww2.model.item.interfaces.IUseable;
import com.itita.ww2.model.user.UserProfile;
import com.itita.ww2.utils.DataUtil;
import com.itita.ww2.utils.random.RandomSelector;
import com.smartfoxserver.v2.entities.data.ISFSObject;
import com.smartfoxserver.v2.entities.data.SFSObject;

public class ChestPropStrategy implements IUseable {
	private static final Logger logger = LoggerFactory.getLogger(ChestPropStrategy.class);
	private ItemProp itemProp;
	//
	private final String ruleId;
	private final RuleType ruleType;
	private final ContentType contentType;
	private final int param;

	public ChestPropStrategy(ItemProp itemProp) {
		this.itemProp = itemProp;
		this.ruleId = (String) this.itemProp.getEffValue();
		this.ruleType = ChestRuleConfig.getRuleType(ruleId);
		this.contentType = ChestRuleConfig.getContentType(ruleId);
		this.param = ChestRuleConfig.getParam(ruleId);
	}

	@Override
	public ISFSObject use(UserProfile userProfile, ISFSObject params) throws WW2Exception {
		ISFSObject ref = SFSObject.newInstance();
		ISFSObject contentObj = SFSObject.newInstance();
		switch (contentType) {
		case ARMY:
			contentObj = findContent();
			openArmy(userProfile.getArmyManager(), contentObj);
			ref.putSFSObject("response", contentObj);
			break;
		case ITEM:
			contentObj = findContent();
			openItem(userProfile.getInventory(), contentObj);
			ref.putSFSObject("response", contentObj);
			break;
		default:
			logger.error("Error ContentType : {}:{}", contentType, contentType.toString());
			break;
		}
		return ref;
	}

	private void openItem(UserInventoryManager userInventory, ISFSObject itemObj) {
		userInventory.addItems(itemObj);
	}

	private ISFSObject openArmy(UserArmyManager userArmyMgr, ISFSObject armyObj) {
		boolean withUnlock = param == 1;
		for (String key : armyObj.getKeys()) {
			if (withUnlock) {
				if (!userArmyMgr.isArmyUnlocked(key)) {
					userArmyMgr.unlockArmy(key, armyObj.getInt(key));
				}
			} else {
				userArmyMgr.armyCountOper(key, armyObj.getInt(key), true);
			}
		}
		userArmyMgr.update();
		userArmyMgr.syncArmy();
		return armyObj;
	}

	private ISFSObject findContent() {
		ISFSObject ref = SFSObject.newInstance();
		switch (ruleType) {
		case FIXED: // 固定宝箱
			ref = findFixedContent();
			break;
		case RANDOM: // 随机宝箱
			ref = findRandomContent();
			break;
		case FIXED_RANDOM: // 混合宝箱
			ref = DataUtil.mergeSFSObject(findFixedContent(), findRandomContent());
			break;
		default:
			logger.error("Error Chest Rule ID: {}", ruleId);
			break;
		}
		return ref;
	}

	private ISFSObject findFixedContent() {
		return ChestRuleConfig.getFixedList(this.ruleId);
	}

	private ISFSObject findRandomContent() {
		boolean isCountRandom = ChestRuleConfig.isCountRandom(this.ruleId);
		int realCount = 0; // 获取实际需求数量
		if (isCountRandom) {
			RandomSelector<Integer, Number> selector = new RandomSelector<>(
					ChestRuleConfig.getCountAsPairList(this.ruleId));
			realCount = selector.random();
		} else {
			realCount = ChestRuleConfig.getCountAsInt(this.ruleId);
		}
		// 随机获取奖励列表
		RandomSelector<String, Number> selector = new RandomSelector<>(
				ChestRuleConfig.getRandomListAsPairList(this.ruleId));
		RandomType r_type = ChestRuleConfig.getRandomType(this.ruleId);

		AtomicLongMap<String> countMap = AtomicLongMap.create();
		if (r_type == RandomType.ONLYFIRST) {
			countMap = selector.randomMulti(realCount);
		} else if (r_type == RandomType.EVERYTIMES) {
			countMap = selector.randomMultiTimes(realCount);
		}
		ISFSObject ref = SFSObject.newInstance();
		for (Entry<String, Long> entry : countMap.asMap().entrySet()) {
			ref.putInt(entry.getKey(), entry.getValue().intValue());
		}
		return ref;
	}

}
